//
//  MKMapView+CLExtension.m
//  CLExtension
//
//  Created by CharlieLiao on 2017/12/14.
//  Copyright © 2017年 Charlie. All rights reserved.
//

#import "MKMapView+CLExtension.h"
//#import "RLMapHelper.h"

//@interface MapDataMode: NSObject
//
//@property (nonatomic) BOOL showsUserLocation;
//@property (nonatomic) MKUserTrackingMode userTrackingMode;
//
//@property (nonatomic, weak) MKMapView *mapView;
//@property (nonatomic, copy) void(^callBack)(MapSourceType type);
//
//- (MapDataMode*)init:(MKMapView*)mapView callBack:(void(^)(MapSourceType type))callBack;
//
//@end
//
//@implementation MapDataMode
//
//- (MapDataMode*)init:(MKMapView*)mapView callBack:(void(^)(MapSourceType type))callBack {
//    self = [super init];
//    if (self) {
//        self.userTrackingMode = mapView.userTrackingMode;
//        self.showsUserLocation = mapView.showsUserLocation;
//        self.mapView = mapView;
//        self.callBack = callBack;
//    }
//    return self;
//}
//
//@end
//
//@interface MapCLExtension: NSObject <CLLocationManagerDelegate> {
//@private NSMutableArray<MapDataMode*> *_maps;
//}
//
//@property (nonatomic, readonly) NSMutableArray<MapDataMode*>*maps;
//@property (nonatomic, strong) CLGeocoder *geocoder;
//
//@end
//
//static CLLocationManager *_locationManager;
//static MapCLExtension *_model;
//
//@implementation MapCLExtension
//
//- (NSMutableArray<MapDataMode *> *)maps {
//    if (_maps == nil) {
//        _maps = [NSMutableArray array];
//    }
//    return _maps;
//}
//
///// 响应当前位置的更新，在这里记录最新的当前位置
//- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
//    MKMapView *mapView;
//    for (MapDataMode *model in self.maps) {
//        if (model.mapView != nil) {
//            mapView = model.mapView;
//            break;
//        }
//    }
//    
//    if (!mapView.userLocation.isUpdating) {
//        CLLocation *mapLocation = mapView.userLocation.location;
//        if (mapLocation) {
//            //停止定位
//            [manager stopUpdatingLocation];
//            
//            //
//            CLLocation *userLocation = locations.lastObject;
//            CLLocationDistance distance = [userLocation distanceFromLocation:mapLocation];
//            // 两坐标偏移太大
//            CLLocationDistance offset = 50;
//            if (distance > offset && distance < -offset) {
//                // 用火星坐标转换试试
//                CLLocationCoordinate2D coordinate = [RLMapHelper wgs84ToGcj02:userLocation.coordinate];
//                CLLocation *newUserLocation = [[CLLocation alloc] initWithCoordinate:coordinate altitude:userLocation.altitude horizontalAccuracy:userLocation.horizontalAccuracy verticalAccuracy:userLocation.verticalAccuracy course:userLocation.course speed:userLocation.speed timestamp:userLocation.timestamp];
//                CLLocationDistance distance = [newUserLocation distanceFromLocation:mapLocation];
//                
//                if (distance > offset && distance < -offset) { // 两坐标偏移太大 Geocoder 查询地址
//                    if (_geocoder)
//                        [_geocoder cancelGeocode];
//                    else
//                        _geocoder = [CLGeocoder new];
//                    
//                    //需要拿到当前位置所属国家，地图是否使用纠偏算法提供判断
//                    [_geocoder reverseGeocodeLocation:userLocation completionHandler:^(NSArray *array, NSError *error) {
//                        NSString *countryCode = [array.firstObject ISOcountryCode];
//                        
//                        MapSourceType type;
//                        if (countryCode && countryCode.length >= 1)
//                            type = [countryCode isEqualToString:@"CN"] ? MapSourceTypeAMap:MapSourceTypeOther;
//                        else
//                            type = MapSourceTypeUnKnown;
//                        
//                        for (NSInteger i = _model.maps.count-1; 0 <= i; i--) {
//                            MapDataMode *mapData = _model.maps[i];
//                            mapData.mapView.showsUserLocation = mapData.showsUserLocation;
//                            mapData.mapView.userTrackingMode = mapData.userTrackingMode;
//                            if (mapData.callBack != nil) mapData.callBack(type);
//                        }
//                        _model = nil;
//                    }];
//                    
//                } else {
//                    // 火星坐标
//                    for (NSInteger i = _model.maps.count-1; 0 <= i; i--) {
//                        MapDataMode *mapData = _model.maps[i];
//                        mapData.mapView.showsUserLocation = mapData.showsUserLocation;
//                        mapData.mapView.userTrackingMode = mapData.userTrackingMode;
//                        if (mapData.callBack != nil) mapData.callBack(MapSourceTypeAMap);
//                    }
//                    _model = nil;
//                }
//                
//            } else {
//                // 地球坐标
//                for (NSInteger i = _model.maps.count-1; 0 <= i; i--) {
//                    MapDataMode *mapData = _model.maps[i];
//                    mapData.mapView.showsUserLocation = mapData.showsUserLocation;
//                    mapData.mapView.userTrackingMode = mapData.userTrackingMode;
//                    if (mapData.callBack != nil) mapData.callBack(MapSourceTypeOther);
//                }
//                _model = nil;
//            }
//            
//            _locationManager = nil;
//        }
//    }
//}
//
//@end


@implementation MKMapView (CLExtension)

///// 是否使用高德地图数据源
//- (void)isUseAMapSource:(void(^)(MapSourceType type))block {
//    
//    if (_model == nil) _model = [MapCLExtension new];
//    
//    if (_locationManager == nil) {
//        _locationManager = [[CLLocationManager alloc] init];
//        _locationManager.distanceFilter = kCLDistanceFilterNone;
//        _locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
//        _locationManager.delegate = _model;
//    }
//    
//    //
//    if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined)
//        [_locationManager requestWhenInUseAuthorization];
//    
//    //
//    MapDataMode *mapData = [[MapDataMode alloc] init:self callBack:block];
//    [_model.maps addObject:mapData];
//    
//    //
//    if (!self.showsUserLocation) {
//        self.userTrackingMode = MKUserTrackingModeNone;
//        self.showsUserLocation = true;
//    }
//    
//    //
//    [_locationManager startUpdatingLocation];
//}

#pragma mark - 一屏幕显示完所有的annotation/Overlay
/*****************************************
 一屏幕显示完所有的annotation
 *****************************************/
#define MINIMUM_ZOOM_ARC 0.014 //approximately 1 miles (1 degree of arc ~= 69 miles)
#define ANNOTATION_REGION_PAD_FACTOR 1.15
#define MAX_DEGREES_ARC 360
//size the mapView region to fit its annotations
- (void)zoomMapViewToFitAnnotationsAnimated:(BOOL)animated
{
    NSArray *annotations = self.annotations;
    int count = (int)[annotations count];
    if (count == 0) return;  //bail if no annotations
    
    //convert NSArray of id <MKAnnotation> into an MKCoordinateRegion that can be used to set the map size
    //can't use NSArray with MKMapPoint because MKMapPoint is not an id
    MKMapPoint points[count]; //C array of MKMapPoint struct
    for( int i=0; i<count; i++ ) //load points C array by converting coordinates to points
    {
        CLLocationCoordinate2D coordinate = [(id <MKAnnotation>)[annotations objectAtIndex:i] coordinate];
        points[i] = MKMapPointForCoordinate(coordinate);
    }
    //create MKMapRect from array of MKMapPoint
    MKMapRect mapRect = [[MKPolygon polygonWithPoints:points count:count] boundingMapRect];
    //convert MKCoordinateRegion from MKMapRect
    MKCoordinateRegion region = MKCoordinateRegionForMapRect(mapRect);
    
    //add padding so pins aren't scrunched on the edges
    region.span.latitudeDelta  *= ANNOTATION_REGION_PAD_FACTOR;
    region.span.longitudeDelta *= ANNOTATION_REGION_PAD_FACTOR;
    //but padding can't be bigger than the world
    if( region.span.latitudeDelta > MAX_DEGREES_ARC ) { region.span.latitudeDelta  = MAX_DEGREES_ARC; }
    if( region.span.longitudeDelta > MAX_DEGREES_ARC ){ region.span.longitudeDelta = MAX_DEGREES_ARC; }
    
    //and don't zoom in stupid-close on small samples
    if( region.span.latitudeDelta  < MINIMUM_ZOOM_ARC ) { region.span.latitudeDelta  = MINIMUM_ZOOM_ARC; }
    if( region.span.longitudeDelta < MINIMUM_ZOOM_ARC ) { region.span.longitudeDelta = MINIMUM_ZOOM_ARC; }
    //and if there is a sample of 1 we want the max zoom-in instead of max zoom-out
    if( count == 1 )
    {
        region.span.latitudeDelta = MINIMUM_ZOOM_ARC;
        region.span.longitudeDelta = MINIMUM_ZOOM_ARC;
    }
    
    region.span.latitudeDelta = region.span.latitudeDelta * 2;//缩小竖方向，方便截图
    [self setRegion:region animated:animated];
}

- (void)zoomMapViewToFitOverlaysAnimated:(BOOL)animated
{
    NSArray *overlays = self.overlays;
    int count = (int)[overlays count];
    if ( count == 0)  return;  //bail if no annotations
    
    //convert NSArray of id <MKAnnotation> into an MKCoordinateRegion that can be used to set the map size
    //can't use NSArray with MKMapPoint because MKMapPoint is not an id
    MKMapPoint points[count]; //C array of MKMapPoint struct
    for( int i=0; i<count; i++ ) //load points C array by converting coordinates to points
    {
        CLLocationCoordinate2D coordinate = [(id <MKOverlay>)[overlays objectAtIndex:i] coordinate];
        points[i] = MKMapPointForCoordinate(coordinate);
    }
    //create MKMapRect from array of MKMapPoint
    MKMapRect mapRect = [[MKPolygon polygonWithPoints:points count:count] boundingMapRect];
    //convert MKCoordinateRegion from MKMapRect
    MKCoordinateRegion region = MKCoordinateRegionForMapRect(mapRect);
    
    //add padding so pins aren't scrunched on the edges
    region.span.latitudeDelta  *= ANNOTATION_REGION_PAD_FACTOR;
    region.span.longitudeDelta *= ANNOTATION_REGION_PAD_FACTOR;
    //but padding can't be bigger than the world
    if( region.span.latitudeDelta > MAX_DEGREES_ARC ) { region.span.latitudeDelta  = MAX_DEGREES_ARC; }
    if( region.span.longitudeDelta > MAX_DEGREES_ARC ){ region.span.longitudeDelta = MAX_DEGREES_ARC; }
    
    //and don't zoom in stupid-close on small samples
    if( region.span.latitudeDelta  < MINIMUM_ZOOM_ARC ) { region.span.latitudeDelta  = MINIMUM_ZOOM_ARC; }
    if( region.span.longitudeDelta < MINIMUM_ZOOM_ARC ) { region.span.longitudeDelta = MINIMUM_ZOOM_ARC; }
    //and if there is a sample of 1 we want the max zoom-in instead of max zoom-out
    if( count == 1 )
    {
        region.span.latitudeDelta = MINIMUM_ZOOM_ARC;
        region.span.longitudeDelta = MINIMUM_ZOOM_ARC;
    }
    [self setRegion:region animated:animated];
}


@end
